home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / tools / ask / dicex / source / dicex.s < prev   
Text File  |  1999-05-30  |  25KB  |  999 lines

  1. *********************************************************************
  2. *    ASK3アクセサリ DicEx
  3. *        Copyright (C) 1996-98 by AIG-Soft
  4. *********************************************************************
  5.  
  6.     .include    defines.mac
  7.     .include    pspdef.mac
  8.     .include    ask3.mac
  9.  
  10. *********************************************************************
  11. *    常駐ルーチン
  12. *********************************************************************
  13. * 常駐物なのでメモリー内配置を確定するため、常駐ルーチン内では.text以外は使わない
  14.  
  15.     .text
  16.     .even
  17. KEEP_START:
  18.     * 常駐確認用識別子
  19. id:    .dc.b    'DicEx V2.2',19,99,'AIG-Soft',0
  20.  
  21. *********************************************************************
  22. * ワーク1
  23. *********************************************************************
  24. * ここに置くワークは、常駐前に初期値が必要な(初期化される)もの
  25.  
  26. ACCS    equ    2    * 組み込むアクセサリの数
  27.  
  28.     .even
  29. ACh        .dcb.l    ACCS,-1    * アクセサリ(初期値-1<0)
  30. all        .dc.l    0    * ワークエリアサイズ
  31. DicList        .dc.l    0    * 0=NULL : 辞書名アドレスアドレス
  32. Gakushu        .ds.l    1    * 学習モード(0=メモリ,1=ディスク)アドレス
  33. Dics        .ds.w    1    * 登録辞書数
  34. dicm        .dc.w    0    * 現在参照中の辞書番号
  35. first        .dc.b    $ff    * DicChangeList:初期起動(=0:初期でない,!=0:初期)
  36. fhigh        .dc.b    $ff    * 高位メモリー確保(=0:No,!=0:Yes)
  37.  
  38. ********************************************************************
  39.  
  40. ErrNotFound:    .dc.b    'は見つかりません',0
  41. MesDicSelect:    .dc.b    '辞書選択',0
  42.     .even
  43.  
  44. ********************************************************************
  45.  
  46. BREAKOFF:
  47. * d0のみ破壊
  48.     move.w    #-1,-(sp)    * read BREAK mode
  49.     DOS    _BREAKCK
  50.     move.w    d0,brksts
  51.     clr.w    -(sp)        * BREAK Cut
  52.     DOS    _BREAKCK
  53.     addq.w    #2*2,sp
  54.     rts
  55.  
  56. ********************************************************************
  57.  
  58. CalcDicList:
  59. * 入力:d1.w=dicm
  60. * 出力:a2  =DicList[dicm]
  61. * 破壊:d0.l,a2
  62.     move.w    d1,d0
  63.     add.w    d0,d0            * *2
  64.     add.w    d0,d0            * *4
  65.     move.l    DicList(pc),a2
  66.     move.l    (a2,d0.w),a2        * dname=DicList[dicm]
  67.     rts
  68.  
  69. DicChangeSub:                * d1.w=dicm
  70. * d0-d1,a0-a2破壊
  71.     bsr    CalcDicList        * a2=DicList[dicm(d1.w)]
  72.     *
  73.     move.l    a2,-(sp)
  74.     move.l    a2,-(sp)
  75.     pea    32.w
  76.     DOS    _KNJCTRL        * 辞書名登録
  77.     lea    4*3(sp),sp
  78.     tst.l    d0
  79.     bne    DERR            * goto DERR
  80.     *
  81.     moveq.l    #0,d0            * for .b -> .l
  82.     move.l    Gakushu(pc),a1
  83.     move.b    (a1,d1.w),d0        * &Gakushu[dicm]
  84.     move.l    d0,-(sp)
  85.     pea    11.w
  86.     DOS    _KNJCTRL        * 学習モード設定
  87.     pea    2.w
  88.     DOS    _KNJCTRL        * 現在の変換モードを記録
  89.     move.l    d0,d1            * ret保存
  90.     pea    0.w
  91.     pea    1.w
  92.     DOS    _KNJCTRL        * ASK終了
  93.     move.l    d1,-(sp)        * ret
  94.     pea    1.w
  95.     DOS    _KNJCTRL        * ASK再起動
  96.     lea    4*7(sp),sp
  97.     tst.l    d0
  98.     beq    17f            * -> OK (d0.l=0)
  99. DERR:    * ASK再起動エラー(辞書がない時はここでエラーが出る)
  100.     lea    cbuf(pc),a1        * cbuf
  101.     move.l    a1,a0            * a0=cbuf
  102. @@:    move.b    (a2)+,(a1)+        * cbuf <- dname
  103.     bne    @b
  104.     subq.w    #1,a1            * cbufのEOSに戻す
  105.     lea    ErrNotFound(pc),a2
  106. @@:    move.b    (a2)+,(a1)+        * cbuf <<- "..."
  107.     bne    @b
  108.     *
  109.     move.l    #kbuf,d0
  110.     moveq.l    #0,d1            * 通常表示
  111.     bsr    Str2MEANS        * kbuf[Str2MEAN(cbuf,kbuf,0)]=0;
  112.     move.l    #DF_KWINSTR|CACI_NORMAL,d0    (d0.l<>0)
  113. 17:    *
  114.     rts
  115.  
  116. **********************************
  117.  
  118. DicChangeList:
  119. * アクセサリ本体
  120. * 入力:4+2(sp) = BIT16K キーコード
  121. * 出力:d0.w    = リターンコード
  122.     move.w    Dics(pc),d2        * Dics
  123.     cmp.w    #1,d2            * Dics<=1?
  124.     bhi    @f            * No : Dics>=2
  125.     * 辞書が1つの時は何もしない
  126.     move.w    #CACI_END,d0        * Yes
  127.     rts
  128. *
  129. @@:    move.w    4+2(sp),d2        * BIT16K キーコード
  130.     move.l    d3,-(sp)        * push d3
  131.     move.w    #CACI_NORMAL,d3        * ret=規定外キー入力の時のため
  132.     *
  133.     bsr    BREAKOFF
  134.     * キーを探して各ルーチンへ飛ぶ
  135.     lea    Jtable(pc),a0
  136.     move.w    d2,d1
  137.     and.w    #NAKEY,d1
  138. @@:    move.l    (a0)+,d0    * jump|code
  139.     beq    @f        * -> end of table
  140.     cmp.w    d1,d0        * =code?
  141.     bne    @b        * no
  142.     swap    d0        * d0=jump
  143.     move.w    dicm(pc),d1    * dicmを引数とする
  144.     jsr    -4(a0,d0.w)
  145.     *
  146. @@:    bsr    BREAKON
  147.     *
  148.     moveq.l    #0,d0            * for .w = .l
  149.     move.w    d3,d0
  150.     move.l    (sp)+,d3        * pop d3
  151.     rts
  152.  
  153. *------------------------------------
  154.  
  155. Jtable:    * 各キー毎のジャンプテーブル(出てきやすい順に並べる)
  156.     * jump先(offset),code
  157.     * CTRL+XF3         : 起動/終了
  158.     * ↑↓/XF3/SHIFT+XF3 : 内容選択
  159.     * CR                 : 決定&終了
  160.     * ESC                : 終了
  161.     .dc.w    xf3key-$,NOT_ASCII|XF3_KEY
  162.     .dc.w    crkey-$,CR
  163.     .dc.w    downkey-$,NOT_ASCII|DOWN_KEY
  164.     .dc.w    upkey-$,NOT_ASCII|UP_KEY
  165.     .dc.w    esckey-$,ESC
  166.     .dc.w    0,0            * end of table
  167.  
  168. *------------------------------------
  169.  
  170. crkey:    * CR : 決定終了
  171.     bsr    DicChangeSub        * 辞書変更
  172.     move.l    d0,d3            * ret=...
  173.     beq    esckey            * =0 : end
  174.     rts
  175.  
  176. xf3key:    * XF3系
  177.     btst.l    #B_CTRL_ON,d2        * btstは.b/.lしかないため
  178.     beq    1f            * CTRL+XF3でない
  179.     * CTRL+XF3:起動
  180.     tst.b    first
  181.     bne    @f
  182.     * 2回目はキャンセルで終了
  183. esckey:    * ESC
  184.     st    first            * first=$ff
  185.     move.w    #CACI_END,d3        * 終了
  186.     rts
  187. *
  188. @@:    * 起動した -> 変更
  189.     clr.b    first            * first=0(sf firstでも全く同じ;同サイズ/クロック)
  190.     *
  191.     lea    MesDicSelect(pc),a0
  192.     move.l    #mbuf,d0
  193.     moveq.l    #1,d1            * 反転表示
  194.     bsr    Str2MEANS        * mbuf[Str2MEAN("辞書選択",mbuf,1)]=0;
  195.     *
  196.     pea    kbuf(pc)        * サブ辞書
  197.     lea    cbuf(pc),a0
  198.     pea    (a0)            * メイン辞書
  199.     pea    41.w
  200.     DOS    _KNJCTRL
  201.     lea    4*3(sp),sp
  202.     move.w    #DF_KWINSTR|DF_MWINSTR|CACI_NORMAL,d3
  203.     bra    Retcp
  204.  
  205. 1:    * CTRL付きでない時は単なる選択
  206.     btst.l    #B_SHIFT_ON,d2
  207.     beq    downkey            * XF3 = ↓
  208.     * SHIFT+XF3 = ↑
  209. upkey:    * ↑
  210.     subq.w    #1,d1            * --dicm
  211.     bpl    DEX
  212.     move.w    Dics(pc),d1        * <0の時
  213.     subq.w    #1,d1            * dicm=Dics-1
  214.     bra    DEX
  215. *
  216. downkey:* ↓
  217.     addq.w    #1,d1            * ++dicm
  218.     cmp.w    Dics(pc),d1        * dicm>=Dics?
  219.     blt    DEX            * no
  220.     moveq.l    #0,d1            * >=の時
  221. DEX:    move.w    d1,dicm
  222.     move.w    #DF_KWINSTR|CACI_NORMAL,d3
  223.     * 変換ラインに表示
  224.     bsr    CalcDicList        * a2=DicList[dicm(d1.w)]
  225.     move.l    a2,a0
  226. Retcp:    move.l    #kbuf,d0
  227.     moveq.l    #0,d1            * 通常表示
  228.     * 以下サブルーチンにつながる        * kbuf[Str2MEAN(a2,kbuf,0)]=0;
  229. Str2MEANS:
  230. * buf[Str2MEAN(mes,buf,mode)]=0
  231. * a0   <- mes
  232. * d0.l <- buf
  233. * d1.l <- mode (0=通常表示,1=反転表示)
  234.     move.l    d1,-(sp)    * mode
  235.     move.l    d0,-(sp)    * buf
  236.     pea    (a0)        * mes
  237.     pea    62.w
  238.     DOS    _KNJCTRL
  239.     lea    4*4(sp),sp
  240.     move.l    -8(sp),a0    * buf
  241.     add.w    d0,d0        * .w=MEAN
  242.     clr.w    (a0,d0.w)    * buf[..]=0
  243.     rts
  244.  
  245. ********************************************************************
  246.  
  247. DicEXchangeSub:
  248. * d1.w <- dicm
  249.     bsr    BREAKOFF
  250.     bsr    DicChangeSub    * d1.w=dicm
  251.     * 以下サブルーチンにつながる
  252. BREAKON:
  253. * d0のみ破壊
  254.     move.w    brksts(pc),-(sp)
  255.     DOS    _BREAKCK
  256.     addq.w    #2,sp
  257.     rts
  258.  
  259. DicEXchange:
  260.     moveq.l    #1,d1        * dicm=でも使う
  261.     cmp.w    Dics(pc),d1    * Dics<=1?
  262.     bge    1f
  263.     lea    dicm(pc),a1
  264.     tst.w    (a1)        * dicm=0?
  265.     beq    @f        * Yes(dicm<-1)
  266.     * dicm<>0 -> dicm=0
  267.     moveq.l    #0,d1
  268. @@:    move.w    d1,(a1)        * dicm=0/1
  269.     bsr    DicEXchangeSub
  270. 1:    move.l    #CACI_END,d0
  271.     rts
  272.  
  273. *********************************************************************
  274. * ワーク2
  275. *********************************************************************
  276. * ここに置くワークは、常駐後に使われるもの
  277. * これらのワークエリアは常駐後に利用可能になるので、
  278. * 以下の非常駐ルーチンからは参照しないこと
  279.  
  280. * 常駐後に非常駐部分をワークエリアにする定義
  281. mbufsz    equ    2*M_SIZE    * .ds.w MSIZE
  282. kbufsz    equ    2*K_SIZE    * .ds.w K_SIZE
  283. cbufsz    equ    C_SIZE        * .ds.b C_SIZE
  284.  
  285. mbuf:
  286. kbuf        equ    mbuf+mbufsz
  287. cbuf        equ    kbuf+kbufsz
  288. brksts        equ    cbuf+cbufsz    * .ds.w 1
  289. WORK_END    equ    brksts+2
  290.  
  291. *********************************************************************
  292. * ワークエリア転送ルーチン
  293. *********************************************************************
  294. * ワークエリアを低位メモリーに取るとき、mallocではなく常駐メモリーを多く取って
  295. * プログラムの後ろに付ける。これは、メモリーの分断を防ぐためである。
  296. *
  297. TrnsWork:
  298. * /hがないとき+常駐終了時のみここにくる
  299. * a0,a2<- 元のDicList
  300. * a1   <- KEEP_END
  301. * d0.l <- ワークエリアサイズ
  302. * d6.l <- 常駐サイズ
  303. * d7.l <- exit code
  304.     * 転送
  305. @@:    move.b    (a0)+,(a1)+    * 元DicList->KEEP_END
  306.     dbra    d0,@b
  307.     * 高位メモリーワーク解放
  308.     pea    (a2)        * DicList
  309.     DOS    _MFREE
  310.     addq.w    #4,sp        * めんどうなのでエラー処理は省略
  311. ComEnd:    * コマンドライン
  312.     clr.w    -(sp)        * exit(0)相当
  313.     move.l    d6,-(sp)    * 常駐サイズ
  314.     DOS    _KEEPPR
  315. TrnsWorkEnd:
  316.  
  317. *--------------------------------------------------------------------
  318. * 転送ルーチンがWORK_ENDより小さいときはWORK_ENDがKEEP_END、
  319. * 逆の時はTrnsWorkEndがKEEP_END
  320.  
  321. * 常駐部分最後
  322. KEEP_END    equ    WORK_END
  323.         * 常駐固定部分最後+1
  324.  
  325. *********************************************************************
  326. *    非常駐ルーチン
  327. *********************************************************************
  328. * アクセサリ定義構造体
  329. *********************************************************************
  330.  
  331.     .even
  332. ACdef:
  333.     * リストから辞書変更
  334.     .dc.w    KS_EDIT0|KS_EDITING        * 仮入力なし/あり
  335.     .dc.w    CTRL_ON|NOT_ASCII|XF3_KEY    * 呼びだしキー:特殊キーにはNOT_ASCIIも付ける
  336.     .dc.l    DicChangeList
  337.     .dc.l    cbuf                * ASK <-> アクセサリ文字列受け渡し
  338.     .dc.l    kbuf                * 使わないところはNULLでもいいらしい
  339.     .dc.l    mbuf
  340.  
  341.     * 2つの辞書入れ換え
  342.     .dc.w    KS_EDIT0|KS_EDITING        * 仮入力なし/あり
  343.     .dc.w    CTRL_ON|NOT_ASCII|XF5_KEY    * 呼びだしキー
  344.     .dc.l    DicEXchange
  345.     .dc.l    cbuf
  346.     .dc.l    kbuf
  347.     .dc.l    mbuf
  348. ACdef_end:
  349.  
  350. *********************************************************************
  351. *    アクセサリ 組み込み/解除/初期化
  352. *********************************************************************
  353.  
  354.     .even
  355. GetTokenSub:
  356. * バッファー内でSPC/TAB/,を飛ばす
  357. * 入力:a1   = 元のバッファー
  358. * 出力:a1   = スキップ後のアドレス
  359. *    d0.b = 最後の文字
  360. 1:    move.b    (a1),d0
  361.     cmp.b    #SPC,d0
  362.     beq    @f
  363.     cmp.b    #TAB,d0
  364.     beq    @f
  365.     cmp.b    #',',d0
  366.     beq    @f
  367.     rts
  368.  
  369. @@:    addq.l    #1,a1
  370.     bra    1b
  371.  
  372. STRCPY2    macro
  373. * セパレーター直前までのコピー
  374. * (a1)+ -> (a4)+
  375. local    L2,L1,L0
  376. L1:    move.b    (a1)+,d0
  377.     move.b    d0,(a4)+
  378.     beq    L2        * EOS
  379.     cmp.b    #SPC,d0
  380.     beq    L0
  381.     cmp.b    #TAB,d0
  382.     beq    L0
  383.     cmp.b    #',',d0
  384.     beq    L0
  385.     cmp.b    #$1a,d0
  386.     bne    L1
  387. L0:    clr.b    -1(a4)        * EOS
  388. L2:    *
  389.     .endm
  390.  
  391. STRLEN2    macro
  392. * セパレーター直前までの長さ取得
  393. * (a1) -> d4
  394. local    L1,L0
  395. L1:    addq.l    #1,d4        * +1
  396.     move.b    (a1)+,d0
  397.     beq    L0        * EOS
  398.     cmp.b    #SPC,d0
  399.     beq    L0
  400.     cmp.b    #TAB,d0
  401.     beq    L0
  402.     cmp.b    #',',d0
  403.     beq    L0
  404.     cmp.b    #$1a,d0
  405.     bne    L1
  406. L0:    *
  407.     .endm
  408.  
  409. TLMAX    equ    128        * テキストの1行>96
  410.  
  411. FGETSs:
  412. * over255バイト対応FGETS+α
  413. * d6 <- fp
  414. * a1 <- line(破壊)
  415. * eof -> d1.b ($00/$ff)
  416. * len -> d0
  417.     movem.l    d4/d5/d7,-(sp)
  418.     moveq.l    #0,d7        * len=0
  419.     move.l    d7,d5        * cc=0
  420. 2:    pea    1.w
  421.     pea    (a1)
  422.     move.w    d6,-(sp)
  423.     DOS    _READ
  424.     lea    10(sp),sp
  425.     tst.l    d0        * ret
  426.     sle    d1        * d1 <- eof
  427.     ble    1f        * <=0
  428.     move.b    (a1),d4
  429.     cmp.b    #$1a,d4        * EOF
  430.     seq    d1        * d1 <- eof
  431.     beq    1f
  432.     cmp.b    #LF,d4        * 改行
  433.     beq    1f
  434.     addq.l    #1,a1        * buf++
  435.     addq.l    #1,d7        * len++
  436.     cmp.l    #TLMAX,d7    * maxはTLMAX固定
  437.     bcs    @f        * <max
  438.     moveq.l    #-1,d0        * バッファーオーバー
  439.     bra    3f
  440. @@:    move.b    d4,d5        * cc=c
  441.     bra    2b
  442. *
  443. 1:    cmp.b    #CR,d5
  444.     bne    @f
  445.     * CRLFは両方消す
  446.     subq.l    #1,d7        * len--
  447.     subq.l    #1,a1        * buf--
  448. @@:    clr.b    (a1)        * EOS
  449.     move.l    d7,d0        * len
  450. 3:    movem.l    (sp)+,d4/d5/d7
  451.     rts
  452.  
  453.  
  454. ReadFile:
  455. * 1行読み込み
  456. * d6 <- fp
  457. * 行先頭文字 -> d0.b
  458. * eof         -> d1.b ($00/$ff)
  459. * 行先頭     -> a1
  460. 1:    lea    inpptr(pc),a1
  461.     bsr    FGETSs
  462.     tst.l    d0        * len=0?
  463.     bne    @f        * no
  464.     * 入力文字数=0の間ループ=空行を飛ばす
  465.     tst.b    d1        * EOF?
  466.     beq    1b        * No
  467. *
  468. @@:    lea    inpptr(pc),a1
  469.     bsr    GetTokenSub    * -> d0.b
  470.     cmp.b    #';',d0
  471.     beq    1b        * コメント
  472.     tst.b    d1        * EOF?
  473.     beq    @f        * No
  474.     moveq.l    #$1a,d0        * eofがある時は$1aが有るように見せかける
  475. @@:    cmp.b    #$1a,d0        * EOF?
  476.     rts            * 判定結果のフラグを持ってリターン
  477.  
  478. **********************************
  479.  
  480. DicChangeListInit:
  481.     * file open
  482.     move.l    4(sp),d0        * fname
  483.     movem.l    d4-d7/a3-a4,-(sp)
  484.     clr.w    -(sp)
  485.     move.l    d0,-(sp)        * fname
  486.     DOS    _OPEN
  487.     addq.l    #6,sp
  488.     moveq.l    #1,d7            * return(1)のため
  489.     move.w    d0,d6            * fp
  490.     bmi    11f            * file open error
  491.     * 準備
  492.     move.b    #TLMAX,inpptr        * テキスト1行長さ
  493.     * 辞書数チェック
  494.     * [0]には必ず最初の辞書=CONFIGで指定した辞書が入る
  495.     pea    inpptr+2(opc)        * sdic : 実際には使わないので仮のワークを指定
  496.     lea    mdic(opc),a2        * mdic
  497.     pea    (a2)            * mdic
  498.     pea    41.w            * 辞書名読み取り -> mdic
  499.     DOS    _KNJCTRL
  500.     lea    4*3(sp),sp
  501.     moveq.l    #0,d4            * len:辞書ファイル名総長さ
  502. @@:    addq.l    #1,d4
  503.     tst.b    (a2)+            * メイン辞書名長
  504.     bne    @b            * strlen(mdic)+1(EOS)
  505.     *
  506.     moveq.l    #1,d5            * Dics : +1 for Config中のASKの分
  507. @@:    bsr    ReadFile
  508.     beq    1f            * -> EOF
  509.     STRLEN2                * len+=strlen2(buff)
  510.     addq.w    #1,d5            * Dics++
  511.     bra    @b
  512.     *
  513. 1:    move.w    d5,Dics            * 記録
  514.     * 辞書の数からワークエリアを確保する
  515.     * 必要サイズ:sizeof(unchar *)*Dics+Dics+len
  516.     * 確保順  :DicList,Gakushu,DicNames
  517.     move.l    d4,a2            * len(符号拡張させるためa?を使う)
  518.     add.w    d5,a2            * +Dics
  519.     move.w    d5,d0            * Dics
  520.     add.w    d0,d0            *     *2
  521.     add.w    d0,d0            *     *4
  522.     add.w    d0,a2            * +(Dics*4)
  523.     move.l    a2,all            * 全ワークエリアサイズ保存
  524.     move.l    a2,-(sp)
  525.     move.w    #2,-(sp)        * ここでは常に高位メモリーに確保する
  526.     DOS    _MALLOC2
  527.     addq.w    #6,sp
  528.     moveq.l    #2,d7            * return(2)のための準備
  529.     move.l    d0,DicList
  530.     ble    10f            * メモリー確保エラー
  531.     * ワークエリアアドレス確定
  532.     move.l    d0,a2
  533.     move.w    d5,d0            * Dics
  534.     add.w    d0,d0            *     *2
  535.     add.w    d0,d0            *     *4
  536.     lea    (a2,d0.w),a3
  537.     move.l    a3,Gakushu
  538.     lea    (a3,d5.w),a4        * DicNames;その先頭アドレスを特に記録する必要はない
  539.     * メイン辞書名の転送
  540.     move.l    a4,(a2)+        * DicList[0]=DicNames
  541.     lea    mdic(opc),a1        * mdic
  542. @@:    move.b    (a1)+,(a4)+        * EOSまで
  543.     bne    @b
  544.     * Config.sys分の学習モード読み取り
  545.     pea    12.w
  546.     DOS    _KNJCTRL
  547.     addq.l    #4,sp
  548.     move.b    d0,(a3)+        * Gakushu[1]
  549.     * ファイル先頭戻し
  550.     clr.w    -(sp)
  551.     pea    0.w
  552.     move.w    d6,-(sp)        * fp
  553.     DOS    _SEEK
  554.     addq.w    #8,sp
  555.     * 実登録
  556.     * a2=&DicList[1] , a3=Gakushu[1] , a4=&DicNames[..]
  557. @@:    bsr    ReadFile
  558.     beq    2f            * -> EOF
  559.     * 辞書名 , 学習モード
  560.     move.l    a4,(a2)+        * DicList[Dics]=nm
  561.     STRCPY2                * (a1)+ -> (a4)+
  562.     bsr    GetTokenSub        * ->a1
  563.     moveq.l    #1,d7            * 学習on
  564.     cmp.b    #'1',d0
  565.     beq    3f
  566.     moveq.l    #0,d7            * 学習off
  567. 3:    move.b    d7,(a3)+        * 指定なし/指定がおかしい時にはoffにする
  568.     bra    @b
  569.     *
  570. 2:    moveq.l    #0,d7            * ret=0
  571. 10:    move.w    d6,-(sp)        * fp
  572.     DOS    _CLOSE
  573.     addq.l    #2,sp
  574. 11:    move.l    d7,d0
  575.     movem.l    (sp)+,d4-d7/a3-a4
  576.     rts
  577.  
  578. **********************************
  579.  
  580. DeleteAcc:    *** これはGCCの出力したままではないので注意
  581.     * a0=常駐しているルーチンのメモリ管理ポインタ
  582.     movem.l    d3-d4/a0/a3-a4,-(sp)    * a0も保存
  583.     move.l    20+4(sp),a3        * ACh : a0を加えたためずれる
  584.     move.l    24+4(sp),d0        * **DicList
  585.     beq    @f            * DicList=NULLのとき
  586.     move.l    d0,-(sp)
  587.     DOS    _MFREE
  588.     addq.w    #4,sp
  589.     move.l    28+4(sp),a0        * ExAd
  590.     moveq.l    #0,d1            * 起動時の辞書に戻す
  591.     jsr    (a0)
  592. @@:    moveq.l    #0,d4            * ret=0
  593.     lea    ACnames(pc),a4
  594.     moveq.l    #ACCS-1,d3        * アクセサリの数 -1 for dbra
  595. ?168:    tst.l    (a3)            * if ACh[i]>=0?
  596.     bmi    ?164            * No
  597.     pea    MesAcc(OPC)
  598.     DOS    _PRINT
  599.     move.l    (a4),-(sp)        * ACnames[i]
  600.     DOS    _PRINT
  601.     move.l    (a3),-(sp)        * ACh[i]
  602.     pea    61.w
  603.     DOS    _KNJCTRL        * 削除
  604.     lea    16(sp),sp
  605.     move.l    #-1,(a3)        * 削除したの印
  606.     lea    MesAccDel(OPC),a1    * OK message
  607.     tst.l    d0
  608.     jbeq    ?169            * ok
  609.     * Error
  610.     moveq.l    #1,d4            * ret=1
  611.     lea    ErrCantDelAcc(OPC),a1    * error message
  612. ?169:    move.l    a1,-(sp)
  613.     DOS    _PRINT
  614.     addq.w    #4,sp
  615. ?164:    addq.w    #4,a3
  616.     addq.w    #4,a4
  617.     dbra    d3,?168
  618.     
  619.     move.l    d4,d0            * ret
  620.     movem.l    (sp)+,d3-d4/a0/a3-a4    * a0も保存
  621.     rts
  622.  
  623. **********************************
  624.  
  625. AttachAcc:    ***
  626.     movem.l    d3/d5/a3/a4,-(sp)
  627.     move.l    20(sp),d3        * fname
  628.     * ASK version check
  629.     pea    50.w
  630.     DOS    _KNJCTRL        * $ff22
  631.     addq.w    #4,sp
  632.     cmp.l    #299,d0
  633.     bgt    @f
  634.     pea    ErrASK3(OPC)        * ASK ver error
  635.     DOS    _PRINT
  636.     addq.w    #4,sp
  637.     moveq.l    #3,d0            * ret=3
  638.     bra    ?170
  639.     *
  640. @@:    move.l    d3,-(sp)        * fname
  641.     bsr    DicChangeListInit
  642.     addq.w    #4,sp
  643.     *
  644.     moveq.l    #1,d2
  645.     cmp.l    d0,d2
  646.     beq    ?173
  647.     moveq.l    #2,d2
  648.     cmp.l    d0,d2
  649.     bne    ?172
  650. * case 2
  651.     pea    ErrCantGetWrk(OPC)
  652.     bra    @f
  653. * case 1
  654. ?173:    pea    ErrNotFndList(OPC)
  655.     DOS    _PRINT
  656.     move.l    d3,-(sp)        * fname
  657.     DOS    _PRINT
  658.     addq.w    #8,sp
  659.     pea    CrLf(OPC)
  660. @@:    DOS    _PRINT
  661.     addq.w    #4,sp
  662.     move.l    d2,d0            * ret=1/2
  663.     bra    ?170            * return
  664.     *
  665. ?172:    move.l    #ACdef,d5
  666.     lea    ACh(pc),a3
  667.     lea    ACnames(pc),a4
  668.     moveq.l    #ACCS-1,d3        * アクセサリの数 -1 for dbra
  669. ?182:    pea    MesAcc(OPC)
  670.     DOS    _PRINT
  671.     move.l    (a4)+,-(sp)        * アクセサリ名
  672.     DOS    _PRINT
  673.     move.l    d5,-(sp)        * ACdef[i]
  674.     pea    60.w
  675.     DOS    _KNJCTRL
  676.     lea    16(sp),sp
  677.     cmp.l    #-1,d0
  678.     bne    @f
  679.     * error
  680.     pea    ErrCantAttach(OPC)
  681.     DOS    _PRINT
  682.     pea    CrLf(OPC)
  683.     DOS    _PRINT
  684.     pea.l    DicEXchangeSub(pc)
  685.     move.l    DicList(pc),-(sp)    * DicList
  686.     pea    ACh(pc)            * 内部ACh
  687.     bsr    DeleteAcc
  688.     lea    4*5(sp),sp
  689.     moveq.l    #4,d0            * ret=4
  690.     bra    ?170
  691.     *
  692. @@:    move.l    d0,(a3)+        * ACh[i]=ret
  693.     pea    MesAttach(OPC)
  694.     DOS    _PRINT
  695.     addq.w    #4,sp
  696.     add.l    #20,d5
  697.     dbra    d3,?182
  698.     *
  699.     moveq.l    #0,d0            * ret=0
  700. ?170:    movem.l (sp)+,d3/d5/a3/a4
  701.     rts
  702.  
  703. ******************************************************************************
  704. * オプションチェック処理部分に関しては、Oh!X 1992/3のX68000マシン語プログラミングを参照
  705. * この中ではa0は壊さないこと(プロセス管理ポインタを参照するため)
  706.  
  707.     .even
  708. chkarg:    * コマンドライン解析(a2=コマンドライン)
  709.     tst.b    (a2)+        * コマンドラインサイズ = 0?
  710.     beq    usage        * Yes -> 引数は必ず必要なので、無い場合は使用法表示
  711. arglp:    bsr    skipsp        * 空白飛ばし
  712.     tst.b    d0        * end?
  713.     beq    eos        * Yes
  714.     * オプションは -? or /?
  715.     cmp.b    #'-',d0
  716.     beq    chkopt
  717.     cmp.b    #'/',d0
  718.     beq    chkopt
  719. getarg:
  720.     * オプション以外の引数は辞書リストファイル名とみなす
  721.     * nameにその名前を転送
  722.     lea.l    name(pc),a3
  723. getarglp:
  724.     move.b    (a2)+,d0
  725.     cmp.b    #' ',d0        * SPCがあったら終わり
  726.     beq    getargeos
  727.     cmp.b    #TAB,d0        * TABがあったら終わり
  728.     beq    getargeos
  729.     move.b    d0,(a3)+
  730.     beq    eos        * EOSを入れたら終了(この後にオプションはない)
  731.     bra    getarglp
  732. getargeos:
  733.     clr.b    (a3)        * EOS
  734.     bra    arglp        * オプションチェックに戻る
  735.  
  736. chkopt:    * オプションチェック
  737.     addq.w    #1,a2        * skip '-' or '/'
  738.     move.b    (a2)+,d0
  739.     beq    usage        * -/のみでオプションがない
  740.     or.b    #$20,d0        * 小文字化
  741.     lea    flags-2(pc),a6    * 後で+2するため-2しておく
  742. LL1:    addq.w    #2,a6
  743.     tst.b    1(a6)
  744.     beq    usage        * 全オプションチェック終わり -> 規定外オプション
  745.     tst.b    (a6)        * すでにフラグがセットされている?
  746.     bne    LL1        * Yes : 飛ばす(2重指定だからbne usageにしてもいい)
  747.     cmp.b    1(a6),d0    * オプションチェック
  748.     bne    LL1        * 不一致
  749.     st.b    (a6)        * セット
  750.     bra    arglp        * コマンドライン処理へ戻る
  751.  
  752. skipsp:    * 空白飛ばし
  753.     move.b    (a2)+,d0
  754.     cmp.b    #' ',d0
  755.     beq    skipsp
  756.     cmp.b    #TAB,d0        * TAB
  757.     beq    skipsp
  758.     subq.w    #1,a2        * a2が1つ進んでいるので戻す
  759. eos:    rts
  760.  
  761. *********************************************************************
  762. *    メイン
  763. *********************************************************************
  764.  
  765.     .xref    keepchk
  766.     .xref    _ChkEX68
  767.  
  768. main:
  769.     move.l    sp,oldstack    * 元のスタック保存
  770.     lea    initsp(pc),sp    * 初期化中用のスタックに設定
  771.                 * PROGRAM=の時スタックオーバーを起こすのでスタックを変更する
  772.     * タイトル表示
  773.     move.w    #2,-(sp)    * STDERR
  774.     pea    title(pc)    * 文字列
  775.     DOS    _FPUTS        * エラー出力へ
  776.     addq.l    #2+4,sp
  777.     *
  778.     jbsr    _ChkEX68    * EX68のチェック
  779.     bne    Err_EX68    * 動作不可とする(将来外す可能性はある)
  780.     *
  781.     move.l    #(id-KEEP_START),-(sp)    * 識別子の相対位置
  782.     pea.l    (a0)        * 自分のメモリ管理ポインタ
  783.     bsr    keepchk        * 常駐チェック
  784.     lea    4*3(sp),sp
  785.     move.b    d0,d7        * d7 :0=常駐してない , -1=常駐している
  786.     
  787.     bsr    chkarg        * コマンドライン引数チェック
  788.     tst.b    rflag        * -r : 常駐解除?
  789.     beq    keep        * no
  790.  
  791. remove:    * 常駐解除
  792.     tst.b    d7        * 常駐している?
  793.     beq    Err_NoKp    * No -> error
  794.     
  795.     * a0=常駐しているルーチンのメモリ管理ポインタ
  796.     * メモリー管理ポインタを飛ばし、ユーザープログラム先頭へ
  797.     * さらに、ACh/DicListまで飛ばす
  798.     pea    DicEXchangeSub-KEEP_START+PSPSIZ(a0)    * DicEXchangeSubのアドレス
  799.     *
  800.     lea    fhigh-KEEP_START+PSPSIZ(a0),a4        * fhighのアドレス
  801.     tst.b    (a4)                    * ワークは高位メモリー?
  802.     bne    @f                    * Yes
  803.     * 低位メモリー
  804.     clr.l    -(sp)                    * DicList=NULL:解放しない
  805.     bra    1f
  806.     *
  807. @@:    lea    DicList-KEEP_START+PSPSIZ(a0),a4    * 高位メモリーワーク解放
  808.     move.l    (a4),-(sp)                * DicListのアドレス
  809. 1:    pea    ACh-KEEP_START+PSPSIZ(a0)        * AChのアドレス
  810.     bsr    DeleteAcc    * アクセサリ解除
  811.     lea    12(sp),sp
  812.     tst.l    d0
  813.     bne    Err_Kai        * アクセサリ登録削除不可により常駐解除不可
  814.     
  815.     pea.l    MPSIZ(a0)
  816.     DOS    _MFREE        * プログラム本体のメモリー解放
  817.     addq.w    #4,sp
  818.     tst.l    d0
  819.     bmi    Err_Kai        * なぜかメモリー解放出来ない時
  820.     * 常駐解除正常終了
  821.     pea.l    Mesrelease(pc)
  822.     DOS    _PRINT
  823.     addq.w    #4,sp
  824.     clr.w    -(sp)        * exit(0)
  825.     DOS    _EXIT2
  826.  
  827. keep:    * 常駐
  828.     tst.b    d7        * 常駐している?
  829.     bne    Err_DBL        * Yes -> error(2重常駐)
  830.     
  831.     * プログラム起動時にはフリーエリアの全てが起動プログラムに割り当てられているため、
  832.     * これを必要部分以外解放する。そうしないとMALLOCが効かない。
  833.     * a0=プログラムメモリ管理ポインタ
  834.     * a1=プログラム終了アドレス+1(.data,.bssを含む)
  835.     lea    MPSIZ(a0),a0    * メモリー管理ポインタ分を飛ばす
  836.     move.l    a0,ProcAD    * このプロセスの先頭アドレス保存
  837.     sub.l    a0,a1        * 当プログラムサイズ
  838.     move.l    a1,-(sp)    * 確保する領域サイズ
  839.     move.l    a0,-(sp)    * 確保する領域の先頭アドレス
  840.     DOS    _SETBLOCK    * 空き領域確保
  841.     addq.w    #4*2,sp
  842.     tst.l    d0
  843.     bmi    Err_Mem        * 領域が確保できない時=エラー
  844.     *
  845.     lea    name(OPC),a2    * 辞書リストファイル名
  846.     tst.b    (a2)
  847.     beq    Err_NoList    * 辞書リスト指定がない
  848.     pea    (a2)        * 辞書リストファイル名
  849.     bsr    AttachAcc    * アクセサリ組み込み
  850.     addq.w    #4,sp
  851.     tst.l    d0
  852.     bne    Err_Keep    * 組み込みエラー
  853.     *
  854.     * アクセサリも組み込みOK
  855.     pea    MesKeep(OPC)
  856.     DOS    _PRINT
  857.     addq.w    #4,sp
  858.  
  859.     * 常駐終了
  860.     move.l    oldstack(pc),sp        * スタックを戻す
  861.                     * スタックを戻すのでこれ以降、深いスタックを使わないこと
  862.     move.l    #KEEP_END-KEEP_START,d6    * 基本常駐サイズ
  863.     tst.b    hflag            * 高位メモリー?
  864.     bne    ComEnd            * Yes
  865.     * 低位メモリーの時
  866.     clr.b    fhigh            * 低位メモリー確保の印
  867.     * ワークエリアアドレス変更
  868.     * このプロセスの占めるメモリー領域を拡大してワークも入るようにする
  869.     add.l    all(pc),d6        * +ワークエリアサイズ
  870.     move.l    d6,d0
  871.     add.l    #PSPSIZ-MPSIZ,d0    * SETBLOCKにはプロセス管理ポインタ分も含める
  872.     move.l    d0,-(sp)        * new size
  873.     move.l    ProcAD(pc),-(sp)
  874.     DOS    _SETBLOCK
  875.     addq.w    #8,sp
  876.     bmi    Err_Mem            * メモリー不足
  877.     *
  878.     * TrnsWorkを小さくするために、前処理をできるだけこちらに置いている
  879.     * ワークエリアポインターを変更
  880.     move.l    DicList(pc),a2        * 元のDicList
  881.     lea    KEEP_END(pc),a1
  882.     move.l    a1,DicList        * DicListをKEEP_ENDに変更
  883.     move.w    Dics(pc),d1
  884.     move.w    d1,d0
  885.     add.w    d0,d0
  886.     add.w    d0,d0            * Dics*4
  887.     lea    (a1,d0.w),a1        * 新Gakushu
  888.     move.l    a1,Gakushu
  889.     lea    (a1,d1.w),a4        * 新DicNames
  890.     lea    (a2,d0.w),a3        * 旧Gakushu
  891.     lea    (a3,d1.w),a3        * 旧DicNames
  892.     * DicListの各内容も変更
  893.     subq.l    #1,d1            * -1 for dbra
  894.     move.l    a2,a0
  895. @@:    move.l    (a0),d0            * 移動前のアドレス
  896.     sub.l    a3,d0            * オフセット化
  897.     add.l    a4,d0            * 新アドレス化
  898.     move.l    d0,(a0)+
  899.     dbra    d1,@b
  900.     *
  901.     lea    KEEP_END(pc),a1        * (a0) -> (a1)
  902.     move.l    a2,a0            * a0=a2=元のDicList
  903.     move.l    all(pc),d0        * サイズ
  904.     subq.l    #1,d0            * -1 for dbra
  905.     bra    TrnsWork
  906. *
  907. * エラー処理
  908. *
  909. Err_EX68:    * EX68上である
  910.     lea.l    ErrEX68(pc),a0
  911.     bra.s    error
  912. Err_Mem:     * メモリーが不足している
  913.     lea.l    ErrCantGetWrk(OPC),a0    * エラーメッセージの流用
  914.     bra    error
  915. Err_NoList:    * 辞書リスト指定がない
  916.     lea.l    ErrNoList(pc),a0
  917.     bra    error
  918. Err_NoKp:    * 常駐していないのに解除しようとした
  919.     lea.l    ErrNoKeep(pc),a0
  920.     bra    error
  921. Err_DBL:    * 2重常駐
  922.     lea.l    ErrAlreadyKeep(pc),a0
  923.     bra    error
  924. Err_Keep:    * 常駐できない
  925.     lea.l    CantKeep(pc),a0
  926.     bra.s    error
  927. Err_Kai:    * 常駐解除不可
  928.     lea.l    ErrCantRelease(pc),a0
  929.     bra    error
  930. usage:    * 使用法
  931.     lea.l    MesUsage(pc),a0
  932. error:
  933.     move.w    #2,-(sp)    * STDERR
  934.     pea.l    (a0)
  935.     DOS    _FPUTS        * 標準出力へ
  936.     addq.l    #2+4,sp
  937.     move.w    #2,-(sp)    * exit(2)
  938.     DOS    _EXIT2
  939.  
  940. ******************************************************************************
  941. * メッセージ&フラグ
  942. ******************************************************************************
  943.  
  944.     .even
  945. flags:        * work,フラグキャラクター
  946. rflag        .dc.b    0,'r'    * 常駐解除フラグ
  947. hflag        .dc.b    0,'h'    * 高位メモリー確保フラグ
  948.         .dc.b    0,0    * end of tabel
  949.  
  950. ACnames:    * メッセージアドレス表
  951.         .dc.l    AccDicList
  952.         .dc.l    AccDicEx
  953.  
  954. AccDicList:    .dc.b    '辞書リスト選択',0
  955. AccDicEx:    .dc.b    '辞書入れ換え',0
  956.  
  957. MesAcc:        .dc.b    'アクセサリ「',0
  958. MesAccDel:    .dc.b    '」を削除しました',CR,LF,0
  959. ErrCantDelAcc:    .dc.b    '」が削除できません',CR,LF,0
  960.  
  961. ErrASK3:    .dc.b    'ASK v3/codeAではありません',CR,LF,0
  962. ErrNoList:    .dc.b    '辞書リストファイル指定がない',CR,LF,0
  963. ErrNotFndList:    .dc.b    '辞書リストファイルが見つかりません:',0
  964. ErrCantGetWrk:    .dc.b    'ワークエリアが確保できません',CR,LF,0
  965. ErrCantAttach:    .dc.b    '」が登録できません',CR,LF,0
  966. MesAttach:    .dc.b    '」を登録しました'    * CrLfにつながる
  967. CrLf:        .dc.b    CR,LF,0
  968.  
  969. title:        .dc.b    'ASK3/codeAアクセサリ DicEx V2.2',CR,LF
  970.         .dc.b    TAB,'Copyright 1996-99 by AIG-Soft',CR,LF,0
  971. MesKeep:    .dc.b    '常駐しました',CR,LF,0
  972. Mesrelease:    .dc.b    '常駐解除しました',CR,LF,0
  973. ErrNoKeep:    .dc.b    '常駐していません',CR,LF,0
  974. ErrAlreadyKeep:    .dc.b    'すでに常駐しています',CR,LF,0
  975. CantKeep:    .dc.b    '常駐できません',CR,LF,0
  976. ErrCantRelease:    .dc.b    '常駐解除できません',CR,LF,0
  977. MesUsage:    .dc.b    'DicEx [/H /R] 辞書リストファイル名',CR,LF,0
  978. ErrEX68        .dc.b    'EX68上では組み込めません',CR,LF,0
  979.     .even
  980.  
  981. ******************************************************************************
  982. * 非常駐ルーチンが使うワークとスタック
  983. ******************************************************************************
  984.     .bss
  985.     .even
  986. ProcAD        .ds.l    1    * このプロセスの先頭アドレス
  987. oldstack    .ds.l    1    * 元のスタック
  988. name        .ds.b    255    * 辞書リストファイル名
  989. *
  990. inpptr        .ds.b    TLMAX+1
  991. mdic        .ds.b    96    * メイン辞書名
  992. *
  993.     .stack
  994.     .even
  995.         .ds.l    512    * 初期化時に使うスタック
  996. initsp:
  997. ******************************************************************************
  998.     .end    main
  999.